package com.cs543.j.client.comm;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Vector;

import org.json.JSONArray;


import com.cs543.j.client.MobileCloudClient;
import com.cs543.j.client.cloudService.CloudRequestCode;
import com.cs543.j.client.cloudService.filesystem.Entry;
import com.cs543.j.client.cloudService.storage.SendRPCMessage;

import android.content.Context;
import android.provider.Settings.System;
import android.util.Base64;
import android.util.Log;

public class CloudCommunication {

	Context context;
	java.io.File fileDirectory;
	java.io.File attributeDirectory;

	public static final String FILE_STORAGE_DIRECTORY = "file";
	public static final String ATTRIBUTE_STORAGE_DIRECTORY = "attribute";

	public CloudCommunication() {
		this.context = MobileCloudClient.context;

		this.initializeStorage();
	}

	public String lookup(String path) {
		java.io.File target = changeIntoLocalFile(path);

		if (!target.exists() || !target.isDirectory()) {
			Log.i("CloudCommunication" ,"Path not exist : " + path);
			return null;
		}

		JSONArray entryList = new JSONArray();

		for (java.io.File each : target.listFiles()) {
			entryList.put(Entry.nameToJSONObject(each.getName(), each.isDirectory()));
		}

		Log.i("CloudCommunication", "Lookup Entry : " + entryList.length());
		return entryList.toString();
	}
	
	public String upload(String path, String data) {
		byte[] file = Base64.decode(data, Base64.URL_SAFE);

		this.changeIntoLocalFile(path).getParentFile().mkdirs();

		try {
			FileOutputStream fos = new FileOutputStream(this.changeIntoLocalFile(path));
			fos.write(file);
			fos.flush();
			fos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return "done";
	}
	
	public String delete(String path)
	{
		java.io.File target = changeIntoLocalFile(path);
		return target.delete()?"done":"not done";
	}
	
	public String move(String filePath, String newPath) {
		java.io.File target = changeIntoLocalFile(filePath);
		return target.renameTo(changeIntoLocalFile(newPath))?"done":"not done";
	}
	
	public String copy(String originalPath, String targetClientURL, String taregtPath) {
		java.io.File originalFile = changeIntoLocalFile(originalPath);

		List parameter = new Vector();
		if( taregtPath.length() == 1 )
			parameter.add(taregtPath + originalFile.getName());
		else
			parameter.add(taregtPath + Entry.DIRECTORY_DELIMITER + originalFile.getName());
		

		StringBuffer result = new StringBuffer();

		FileInputStream fis;
		try {
			fis = new FileInputStream(originalFile);
			byte[] buffer = new byte[(int) originalFile.length()];

			fis.read(buffer);
			result.append(Base64.encodeToString(buffer, Base64.URL_SAFE));
			fis.close();

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		parameter.add(result.toString());

		SendRPCMessage rpc = new SendRPCMessage(targetClientURL, CloudRequestCode.UPLOAD, parameter, 0, null);
		rpc.start();

		return "done";
	}
	
	public String download(String path, String newPath) {

		java.io.File target = changeIntoLocalFile(path);
		StringBuffer result = new StringBuffer();

		FileInputStream fis;
		try {
			fis = new FileInputStream(target);
			byte[] buffer = new byte[(int) target.length()];

			fis.read(buffer);
			result.append(Base64.encodeToString(buffer, Base64.URL_SAFE));
			fis.close();

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return result.toString();
	}

	private void initializeStorage() {
		java.io.File privateDirectory = context.getFilesDir();
		fileDirectory = new java.io.File(privateDirectory.getPath() + "/" + FILE_STORAGE_DIRECTORY);

		if (!fileDirectory.exists()) {
			fileDirectory.mkdir();
		} else if (!fileDirectory.isDirectory()) {
			fileDirectory.delete();
			fileDirectory.mkdir();
		}

		attributeDirectory = new java.io.File(privateDirectory.getPath() + "/" + ATTRIBUTE_STORAGE_DIRECTORY);

		if (!attributeDirectory.exists()) {
			attributeDirectory.mkdir();
		} else if (!attributeDirectory.isDirectory()) {
			attributeDirectory.delete();
			attributeDirectory.mkdir();
		}
	}

	private java.io.File changeIntoLocalFile(String path) {

		if (path.equals(Entry.DIRECTORY_DELIMITER)) {
			return fileDirectory;
		} else {
			return new java.io.File(fileDirectory.getPath() + path);
		}

	}

}
